<template>
  <div :style="editorStyles">
    <div ref="monacoEditorRef" class="monaco-editor"></div>
  </div>
</template>
<script setup lang="ts">
  import * as monaco from 'monaco-editor';
  import { editor } from 'monaco-editor';
  import { computed, onMounted, ref } from 'vue';

  const props = defineProps({
    width: {
      type: [String, Number],
      default: '100%',
    },
    height: {
      type: [String, Number],
      default: '100%',
    },
  });
  const emit = defineEmits(['onQuery']);

  const editorStyles = computed(() => {
    return {
      width: typeof props.width === 'number' ? `${props.width}px` : props.width,
      height: typeof props.height === 'number' ? `${props.height}px` : props.height,
    };
  });

  const monacoEditorRef = ref<HTMLElement | null>(null);
  const editorOptions: editor.IStandaloneEditorConstructionOptions = {
    value: '',
    language: 'sql',
    theme: 'vs-light',
    fontSize: 16,
    lineHeight: 24,
    automaticLayout: true, // 自动布局
    foldingStrategy: 'indentation', // 代码可分小段折叠
    autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
    autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
    autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
    autoIndent: 'none', // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
    comments: {
      ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
      insertSpace: true, // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
    }, // 注释配置
    //
    // cursorBlinking: "Solid", // 光标动画样式
    // cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
    // cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
    // cursorSurroundingLinesStyle: "all", // "default" | "all" 光标环绕样式
    // cursorWidth: 1, // <=25 光标宽度
    minimap: {
      enabled: true, // 是否启用预览图
      maxColumn: 80, //缩略图列数（控制宽度）
      showSlider: 'always',
    },
    overviewRulerBorder: false, // 是否应围绕概览标尺绘制边框
    readOnly: false,
    folding: true, // 是否启用代码折叠
    scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后
    renderLineHighlight: 'all', // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
    contextmenu: true,
    mouseWheelZoom: true, //鼠标缩放字体大小
    snippetSuggestions: 'bottom',
    scrollbar: {
      verticalScrollbarSize: 0,
      horizontalScrollbarSize: 8,
      handleMouseWheel: true, //
      alwaysConsumeMouseWheel: false, //不阻止滚动事件，让外层还能滚动
    },
  };

  async function initEditor() {
    if (monacoEditorRef.value) {
      const instance = editor.create(monacoEditorRef.value, editorOptions);
      // @ts-ignore ts类型要两个入参，但实测1个做 | 才行。
      const chordNumber = monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter);
      instance.addCommand(chordNumber, () => {
        console.log('ctrl+enter 去执行sql吧');

        // 尝试选择选中文本
        const rangeText = instance.getModel()?.getValueInRange(instance.getSelection() as any);
        let sql = rangeText;
        // console.log(sql);
        if (!sql) {
          sql = instance.getValue();
        }

        // console.log(sql);
        emit('onQuery', { sql });
      });
    }
  }

  onMounted(() => {
    initEditor();
  });
</script>

<style scoped lang="less">
  .monaco-editor {
    width: 100%;
    height: 100%;
    border: 1px solid #e5e5e5;
  }
</style>
